package com.iflytek.education.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iflytek.common.constant.CacheConstants;
import com.iflytek.common.constant.CourseStatusConstants;
import com.iflytek.common.constant.DeletedConstants;
import com.iflytek.common.constant.MqConstants;
import com.iflytek.common.utils.StringUtils;
import com.iflytek.common.utils.bean.BeanUtils;
import com.iflytek.education.domain.EduCourse;
import com.iflytek.education.domain.EduCourseDescription;
import com.iflytek.education.domain.EduSubject;
import com.iflytek.education.domain.EduTeacher;
import com.iflytek.education.domain.vo.CourseQueryVO;
import com.iflytek.education.domain.vo.EduCourseVO;
import com.iflytek.education.mapper.EduCourseDescriptionMapper;
import com.iflytek.education.mapper.EduCourseMapper;
import com.iflytek.education.mapper.EduSubjectMapper;
import com.iflytek.education.mapper.EduTeacherMapper;
import com.iflytek.education.service.IEduCourseService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 课程Service业务层处理
 *
 * @author isahino
 * @date 2023-09-14
 */
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements IEduCourseService {
    @Resource
    private EduCourseMapper eduCourseMapper;
    @Resource
    private EduSubjectMapper eduSubjectMapper;
    @Resource
    private EduTeacherMapper eduTeacherMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private EduCourseDescriptionMapper eduCourseDescriptionMapper;

    /**
     * 查询课程
     *
     * @param id 课程主键
     * @return 课程
     */
    @Override
    public EduCourseVO selectEduCourseById(String id) {
        EduCourse eduCourse = eduCourseMapper.selectEduCourseById(id);
        EduCourseVO eduCourseVO = new EduCourseVO();
        BeanUtils.copyProperties(eduCourse, eduCourseVO);
        eduCourseVO.setSubjectName(eduSubjectMapper.selectById(eduCourse.getSubjectId()).getTitle());
        eduCourseVO.setTeacherName(eduTeacherMapper.selectById(eduCourse.getTeacherId()).getName());
        return eduCourseVO;
    }

    /**
     * 查询课程列表
     *
     * @param eduCourse 课程
     * @return 课程
     */
    @Override
    public List<EduCourseVO> selectEduCourseList(EduCourse eduCourse) {
        List<EduCourse> eduCourses = eduCourseMapper.selectEduCourseList(eduCourse);
        // 封装类别及讲师名称
        List<EduCourseVO> eduCourseVOList = new ArrayList<>(eduCourses.size());
        // 查询所有类别及讲师信息，并转换为map结构
        Map<String, String> teacherMap = eduTeacherMapper.selectList(null).stream().collect(Collectors.toMap(EduTeacher::getId, EduTeacher::getName));
        Map<String, String> subjectMap = eduSubjectMapper.selectList(null).stream().collect(Collectors.toMap(EduSubject::getId, EduSubject::getTitle));
        for (EduCourse e : eduCourses) {
            EduCourseVO eduCourseVO = new EduCourseVO();
            BeanUtils.copyProperties(e, eduCourseVO);
            eduCourseVO.setTeacherName(teacherMap.get(e.getTeacherId()));
            eduCourseVO.setSubjectName(subjectMap.get(e.getSubjectId()));
            eduCourseVOList.add(eduCourseVO);
        }
        return eduCourseVOList;
    }

    /**
     * 新增课程
     *
     * @param eduCourse 课程
     * @return 结果
     */
    @Override
    @CacheEvict(value = "course", allEntries = true)
    public int insertEduCourse(EduCourse eduCourse) {
        eduCourse.setIsDeleted(DeletedConstants.UN_DELETED);
        eduCourse.setStatus(CourseStatusConstants.UN_RELEASE);
        // 查询课程类型父类id
        eduCourse.setSubjectParentId(eduSubjectMapper.queryParentId(eduCourse.getSubjectId()));
        // 新增课程
        eduCourseMapper.insert(eduCourse);
        // 新增课程简介
        EduCourseDescription eduCourseDescription = new EduCourseDescription();
        eduCourseDescription.setId(eduCourse.getId());
        eduCourseDescription.setDescription(eduCourse.getDescription());
        return eduCourseDescriptionMapper.insert(eduCourseDescription);
    }

    /**
     * 修改课程
     *
     * @param eduCourse 课程
     * @return 结果
     */
    @Override
    @CacheEvict(value = "course", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public int updateEduCourse(EduCourse eduCourse) {
        // 若课程名称变化，修改订单表中对应的课程名称信息
        EduCourse eduCourse1 = eduCourseMapper.selectById(eduCourse.getId());
        if (!eduCourse1.getTitle().equals(eduCourse.getTitle())) {
            // 发送异步信息，让订单服务进行更新
            rabbitTemplate.convertAndSend(MqConstants.EDU_EXCHANGE_DIRECT, MqConstants.COURSE_QUEUE, eduCourse);
        }
        // 查询课程类型父类id
        eduCourse.setSubjectParentId(eduSubjectMapper.queryParentId(eduCourse.getSubjectId()));
        // 更新课程简介
        EduCourseDescription eduCourseDescription = new EduCourseDescription();
        eduCourseDescription.setId(eduCourse.getId());
        eduCourseDescription.setDescription(eduCourse.getDescription());
        // 如果课程描述更新失败
        eduCourseDescriptionMapper.updateById(eduCourseDescription);
        return eduCourseMapper.updateById(eduCourse);
    }

    /**
     * 批量删除课程
     *
     * @param ids 需要删除的课程主键
     * @return 结果
     */
    @Override
    @CacheEvict(value = "course", allEntries = true)
    public int deleteEduCourseByIds(String[] ids) {
        // 删除课程简介
        eduCourseDescriptionMapper.deleteBatchIds(Arrays.asList(ids));
        return eduCourseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除课程信息
     *
     * @param id 课程主键
     * @return 结果
     */
    @Override
    @CacheEvict(value = "course", allEntries = true)
    public int deleteEduCourseById(String id) {
        // 删除课程简介
        eduCourseDescriptionMapper.deleteById(id);
        return eduCourseMapper.deleteById(id);
    }

    @Override
    @Cacheable(value = "course", key = CacheConstants.HOT_COURSE_LIST)
    public List<EduCourse> findHotCourse() {
        LambdaQueryWrapper<EduCourse> queryWrapper = new LambdaQueryWrapper<>();
        // 需要已发布的课程才能查询到
        queryWrapper.eq(EduCourse::getStatus, CourseStatusConstants.RELEASED);
        queryWrapper.eq(EduCourse::getIsDeleted, DeletedConstants.UN_DELETED);
        queryWrapper.orderByDesc(EduCourse::getViewCount);
        queryWrapper.last("limit 8");
        return eduCourseMapper.selectList(queryWrapper);
    }

    @Override
    public void queryList(Page<EduCourse> result, CourseQueryVO courseQueryVo) {
        LambdaQueryWrapper<EduCourse> queryWrapper = new LambdaQueryWrapper<>();
        // 初始条件 [未删除、已上架]
        queryWrapper.eq(EduCourse::getIsDeleted, DeletedConstants.UN_DELETED);
        queryWrapper.eq(EduCourse::getStatus, CourseStatusConstants.RELEASED);
        // 根据查询条件封装
        if (!StringUtils.isEmpty(courseQueryVo.getBuyCountSort())) {
            if (CourseStatusConstants.DESC.equals(courseQueryVo.getBuyCountSort())) {
                queryWrapper.orderByDesc(EduCourse::getBuyCount);
            } else {
                queryWrapper.orderByAsc(EduCourse::getBuyCount);
            }
        }
        if (!StringUtils.isEmpty(courseQueryVo.getGmtCreateSort())) {
            if (CourseStatusConstants.DESC.equals(courseQueryVo.getBuyCountSort())) {
                queryWrapper.orderByDesc(EduCourse::getGmtCreate);
            } else {
                queryWrapper.orderByAsc(EduCourse::getGmtCreate);
            }
        }
        if (!StringUtils.isEmpty(courseQueryVo.getPriceSort())) {
            if (CourseStatusConstants.DESC.equals(courseQueryVo.getPriceSort())) {
                queryWrapper.orderByDesc(EduCourse::getPrice);
            } else {
                queryWrapper.orderByAsc(EduCourse::getPrice);
            }
        }
        if (!StringUtils.isEmpty(courseQueryVo.getSubjectParentId())) {
            queryWrapper.eq(EduCourse::getSubjectParentId, courseQueryVo.getSubjectParentId());
        }
        if (!StringUtils.isEmpty(courseQueryVo.getSubjectId())) {
            queryWrapper.eq(EduCourse::getSubjectId, courseQueryVo.getSubjectId());
        }
        page(result, queryWrapper);
    }
}
